{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d6f83f81-aceb-42e3-ad75-f5978c201cdc",
   "metadata": {},
   "source": [
    "# Shor's Algorithm\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83a55311-9ce2-4262-a4fd-de01d8c51420",
   "metadata": {},
   "source": [
    "## Introduction\n",
    "\n",
    "Integer factorization [[1](#IntegerFactor)] is a famous problem in number theory: given a number $N$ which is composite, find its prime factors. The importance of the problem stems from the fact that no efficient (polynomial-time, in the number of bits needed to represent $N$) classical algorithm is known for it to this day, and much of modern day cryptography relies on this fact. In 1994, Peter Shor came up with an efficient _quantum_ algorithm for the problem [[2](#Shor94)] - providing, arguably, the most important evidence for an exponential advantage of quantum computing over classical computing.\n",
    "\n",
    "### The full Algorithm\n",
    "\n",
    "Shor's algorithm consists of a classical part and a quantum subroutine. The steps of the algorithm for factoring an input number $N$, summarized from [[3](#ShorSteps)], are as follows:\n",
    "\n",
    "1. Pick a random number $1 < a < N$ that is co-prime with $N$. Co-primality can be checked by computing the GCD (greatest common divisor) of $a$ and $N$ - if it is 1 then we have found a co-prime $a$, otherwise we have found a non-trivial factor of $N$ and we are done.\n",
    "2. Find the period $r$ of the following function, using the quantum period finding algorithm (described in [[3](#ShorSteps)]): $$f(x) = a^x\\hspace{-8pt} \\mod \\hspace{-4pt} N$$\n",
    "3. If $r$ is odd or $a^{r/2} = -1 \\mod N$, return to step 1 (this event can be shown to happen with probability at most $1/2$).\n",
    "4. Otherwise, $\\gcd(a^{r/2} \\pm 1, N)$ are both factors of $N$, and computing one of them yields the required result.\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "610dbdf9-62ac-4588-933b-733e2ed03f92",
   "metadata": {},
   "source": [
    "### Quantum period finding\n",
    "\n",
    "The quantum part of Shor's algorithm - the period finding is simply quantum phase estimation (QPE) applied to the unitary $U$ which computes multiplication by $a$ modulo $N$: $U|y\\rangle =|ya \\hspace{-6pt}\\mod \\hspace{-4pt} N\\rangle$[[4](#NielsenChuang)]. This unitary is applied to the input state $|y=1\\rangle$ which is an equal superposition of $r$ eigenstates of $U$ ($r$ being the period we wish to find) with eigenvalues \n",
    "$\\exp (2\\pi i s/r)$,  $s = 0, ... ,r-1$. The measured output of the QPE circuit would therefore be a number which is a good approximation to $s/r$ for some $s < r$. The denominator $r$ can be found with some additional classical post-processing [[4](#NielsenChuang)]. \n",
    "The repeated applications of $U^{2^{j}}$ in the QPE algorithm are realized by multiplying with the corresponding powers $a^{2^{j}}$ modulo $N$. The resulting computation (of the repeated multiplications) is exponentiation modulo $N$. The general scheme of the QPE realizing the quantum order finding is shown in the following figure.     \n"
   ]
  },
  {
   "attachments": {
    "e9fc2bd9-113e-4a65-b423-277b082e7456.png": {
     "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbIAAAC8CAYAAAAdDivYAAAKrGlDQ1BJQ0MgUHJvZmlsZQAASImVlwdUU9kWhs+96SGhJYQiJfQmSCeAlBBa6L2JSkgChBJiIKjYEXEEx4KICCiCDkUUHAsggw1RbIOCYtcBGRSUcbBgQ+VdYBFm5q333np7rb3Ol519/rPPWffctS8AZHmOSJQGywOQLswSh3q706NjYum4YQABGBCBDjDmcDNFzOBgf4DY7Ph3+3AXyUbsttmU1r///19NgcfP5AIABSOcwMvkpiN8EvGXXJE4CwDUASSuuzxLNMWdCFPFSIEI35/ipBkeneKEaUaD6ZzwUBbCVADwJA5HnAQAiY7E6dncJESH5IawhZAnECIsQtglPT2Dh/AxhI2QHCRGmtJnJPxFJ+lvmglSTQ4nScoze5k2vIcgU5TGWfl/Hsf/tvQ0yewaBoiTksU+ocioiJzZ/dQMPykLEwKDZlnAm86f5mSJT8QsczNZsbPM43j4SeemBfrPcqLAiy3VyWKHzzI/0zNslsUZodK1EsUs5ixzxHPrSlIjpPFkPluqn5McHjXL2YLIwFnOTA3zm8thSeNiSai0fr7Q231uXS/p3tMz/7JfAVs6Nys53Ee6d85c/Xwhc04zM1paG4/v4TmXEyHNF2W5S9cSpQVL8/lp3tJ4ZnaYdG4W8kDOzQ2WnmEKxzd4lgELZIA0xMWADvyRXx4AZPFXZE1thJUhWikWJCVn0ZnIDePT2UKu+Xy6lYWVDQBT93XmcXhHm76HEO3aXCz3PQDOvMnJyfa5mL8eACc3AUB8PhczPAuArDIAVwq5EnH2TGz6LmGQt4AcoAJVoAl0gREwA1bADjgBN+AJfEEQCAcxYAnggmSQjlS+HKwGG0A+KAQ7wG5QBirBQVAHjoLjoAW0gwvgMrgOboE+8Aj0gyHwCoyBD2ACgiAcRIYokCqkBelDppAVxIBcIE/IHwqFYqB4KAkSQhJoNbQRKoSKoDKoCqqHfoZOQxegq1AP9AAagEagt9AXGAWTYCqsARvAC2AGzIT94HB4MZwEL4Nz4Dx4G1wKV8NH4Gb4Anwd7oP74VfwOAqgZFA0lDbKDMVAsVBBqFhUIkqMWosqQJWgqlGNqDZUF+o2qh81ivqMxqIpaDraDO2E9kFHoLnoZei16K3oMnQduhndib6NHkCPob9jyBh1jCnGEcPGRGOSMMsx+ZgSTA3mFOYSpg8zhPmAxWJpWEOsPdYHG4NNwa7CbsXuwzZhz2N7sIPYcRwOp4ozxTnjgnAcXBYuH7cXdwR3DteLG8J9wsvgtfBWeC98LF6Iz8WX4A/jz+J78S/wEwR5gj7BkRBE4BFWErYTDhHaCDcJQ4QJogLRkOhMDCemEDcQS4mNxEvEx8R3MjIyOjIOMiEyApn1MqUyx2SuyAzIfCYpkkxILFIcSULaRqolnSc9IL0jk8kGZDdyLDmLvI1cT75Ifkr+JEuRNZdly/Jk18mWyzbL9sq+liPI6csx5ZbI5ciVyJ2Quyk3Kk+QN5BnyXPk18qXy5+Wvyc/rkBRsFQIUkhX2KpwWOGqwrAiTtFA0VORp5ineFDxouIgBUXRpbAoXMpGyiHKJcoQFUs1pLKpKdRC6lFqN3VMSVHJRilSaYVSudIZpX4aimZAY9PSaNtpx2l3aV+UNZSZynzlLcqNyr3KH1Xmqbip8FUKVJpU+lS+qNJVPVVTVXeqtqg+UUOrmaiFqC1X2692SW10HnWe0zzuvIJ5x+c9VIfVTdRD1VepH1S/oT6uoanhrSHS2KtxUWNUk6bpppmiWax5VnNEi6LloiXQKtY6p/WSrkRn0tPopfRO+pi2uraPtkS7Srtbe0LHUCdCJ1enSeeJLlGXoZuoW6zboTump6UXoLdar0HvoT5Bn6GfrL9Hv0v/o4GhQZTBZoMWg2FDFUO2YY5hg+FjI7KRq9Eyo2qjO8ZYY4ZxqvE+41smsImtSbJJuclNU9jUzlRgus+0Zz5mvsN84fzq+ffMSGZMs2yzBrMBc5q5v3mueYv56wV6C2IX7FzQteC7ha1FmsUhi0eWipa+lrmWbZZvrUysuFblVnesydZe1uusW63f2Jja8G3229y3pdgG2G627bD9ZmdvJ7ZrtBux17OPt6+wv8egMoIZWxlXHDAO7g7rHNodPjvaOWY5Hnf808nMKdXpsNPwQsOF/IWHFg466zhznKuc+13oLvEuB1z6XbVdOa7Vrs/cdN14bjVuL5jGzBTmEeZrdwt3sfsp948sR9Ya1nkPlIe3R4FHt6eiZ4RnmedTLx2vJK8GrzFvW+9V3ud9MD5+Pjt97rE12Fx2PXvM1953jW+nH8kvzK/M75m/ib/Yvy0ADvAN2BXwOFA/UBjYEgSC2EG7gp4EGwYvC/4lBBsSHFIe8jzUMnR1aFcYJWxp2OGwD+Hu4dvDH0UYRUgiOiLlIuMi6yM/RnlEFUX1Ry+IXhN9PUYtRhDTGouLjYytiR1f5Llo96KhONu4/Li7iw0Xr1h8dYnakrQlZ5bKLeUsPRGPiY+KPxz/lRPEqeaMJ7ATKhLGuCzuHu4rnhuvmDfCd+YX8V8kOicWJQ4nOSftShpJdk0uSR4VsARlgjcpPimVKR9Tg1JrUyfTotKa0vHp8emnhYrCVGFnhmbGiowekakoX9S/zHHZ7mVjYj9xTSaUuTizNYuKNEY3JEaSTZKBbJfs8uxPyyOXn1ihsEK44sZKk5VbVr7I8cr5aRV6FXdVx2rt1RtWD6xhrqlaC61NWNuxTndd3rqh9d7r6zYQN6Ru+DXXIrco9/3GqI1teRp56/MGN3lvasiXzRfn39vstLnyB/QPgh+6t1hv2bvlewGv4FqhRWFJ4det3K3XfrT8sfTHyW2J27q3223fvwO7Q7jj7k7XnXVFCkU5RYO7AnY1F9OLC4rf7166+2qJTUnlHuIeyZ7+Uv/S1r16e3fs/VqWXNZX7l7eVKFesaXi4z7evt79bvsbKzUqCyu/HBAcuF/lXdVcbVBdchB7MPvg80ORh7p+YvxUX6NWU1jzrVZY218XWtdZb19ff1j98PYGuEHSMHIk7sitox5HWxvNGquaaE2Fx8AxybGXP8f/fPe43/GOE4wTjSf1T1acopwqaIaaVzaPtSS39LfGtPac9j3d0ebUduoX819q27Xby88ondl+lng27+zkuZxz4+dF50cvJF0Y7Fja8ehi9MU7nSGd3Zf8Ll257HX5Yhez69wV5yvtVx2vnr7GuNZy3e568w3bG6d+tf31VLddd/NN+5uttxxutfUs7Dnb69p74bbH7ct32Heu9wX29dyNuHv/Xty9/vu8+8MP0h68eZj9cOLR+seYxwVP5J+UPFV/Wv2b8W9N/Xb9ZwY8Bm48C3v2aJA7+Or3zN+/DuU9Jz8veaH1on7Yarh9xGvk1stFL4deiV5NjOb/ofBHxWuj1yf/dPvzxlj02NAb8ZvJt1vfqb6rfW/zvmM8ePzph/QPEx8LPql+qvvM+Nz1JerLi4nlX3FfS78Zf2v77vf98WT65KSII+ZMtwIoxOHERADe1gJAjgGAcgvpHxbN9NPTBs18A0wT+E8803NPmx0Ajcgw1RaxzgNwDHGD9Yi2GwBTLVG4G4CtraU+2/tO9+lThkW+WA54TNGDXQnR4B8208P/pe5/jmBK1Qb8c/wXwV8GumuMvCoAAAA4ZVhJZk1NACoAAAAIAAGHaQAEAAAAAQAAABoAAAAAAAKgAgAEAAAAAQAAAbKgAwAEAAAAAQAAALwAAAAADQv+awAAJFJJREFUeAHtnQd8FMXbx5+E0ALSEYhSQpEuvfcivYNSQxKagAWsoKAUFRVF0b8oLZTQBaQl9BIgAQEFXqmKdKQqIjVASN7n2XDH3eUuubtsdm8vv/l8ILuzM8/MfGdvn52ZZ571SeBACCAAAiAAAiBgUAK+Bq03qg0CIAACIAACCgEoMtwIIAACIAAChiYARWbo7kPlQQAEQAAEoMhwD4AACIAACBiaABSZobsPlQcBEAABEIAiwz0AAiAAAiBgaAJQZIbuPlQeBEAABEAAigz3AAiAAAiAgKEJQJEZuvtQeRAAARAAASgy3AMgAAIgAAKGJgBFZujuQ+VBAARAAASgyHAPgAAIgAAIGJoAFJmhuw+VBwEQAAEQgCLDPQACIAACIGBoAlBkhu4+VB4EQAAEQACKDPcACIAACICAoQlAkRm6+1B5EAABEAABKDLcAyAAAiAAAoYmAEVm6O5D5UEABEAABKDIcA+AAAiAAAgYmgAUmaG7D5UHARAAARCAIsM9AAIgAAIgYGgCUGSG7j5UHgRAAARAAIoM9wAIgAAIgIChCUCRGbr7UHkQAAEQAAEoMtwDIAACIAAChiYARWbo7kPlQQAEQAAEoMhwD4AACIAACBiaABSZobsPlQcBEAABEIAiwz0AAiAAAiBgaAJQZIbuPlQeBEAABEAAigz3AAiAAAiAgKEJQJEZuvtQeRAAARAAASgy3AMgAAIgAAKGJgBFZujuQ+VBAARAAASgyHAPgAAIgAAIGJoAFJmhuw+VBwEQAAEQgCLDPQACIAACIGBoAlBkhu4+VB4EQAAEQACKDPcACIAACICAoQlAkbnRfQkJCW7k8rws3tIOzyOLGnkbAfxWPLtH/Ty7ep5ZOx8fH/Lz8aWcOXN6ZgWdqNV///1HcQnxTqREEhBIHYFXh75CixYuTJ0QHXPfuX2brl7/h3LkyKFjLVB0cgR8+E3DO4YXybVS5Wuff/Y5/bhkCT311FMqS9ZO3P3YWCpTtizNnjtHu0JRUrokkC93Hnq+UiWKjzfui1PLVq3owf1YGjNuXLrsQ09vNEZkbvRQlsyZaeCgQTR4yGA3cntOluCgIM+pDGritQQePHhAW6O2Gbp9V65coVlhswzdBm+uPNbIvLl30TYQAAEQSAcEoMjSQSejiSAAAiDgzQQwtejNvYu2gQAI6EagetVq1Lp1a3r06BGJgdjdu3cpa9asSn3i4h7RfV5zy5Yt2+PzOOWvn1/iIzkuzvr8zp07lJmXNEzX7927R/7+/mQycbhx4wblyZPHvA55YP8BCpsziwICAnRrv5YFQ5FpSduAZV26eIkKBRRyWPN///2XcufO7fA6LoBAeiVQsmRJ+uiTj3Vp/jdfT6aHDx7qUrYehWJqUQ/qBirzg9Gj7dZ2xfLlSvzRI0dpxrTpdtMgEgTSMwHTaEktBteuXnVa1CMDW4g63UiLhFBkFjBwmJRAxowZk0ZyzNGjx5T4evXr0Zo1q+2mQSQIgIB6BHr17KWeMC+TpKkiEzNcV4PMK6d1uB97P62L8Cr5x44do1EfPBmptW3bln755RevaiMaAwKpJSBrY2qFU6dOUblyZZ0Xl86cHWiqyCZ8/DFFRkQ43RmywFmxXHmn07ubsPtLL9KveBA7hS8kqC9FrFlD48eONad/ecgQ+u7bb83nOAABTyewe9fuNK9ihgwZVCtj+dKlVKFCReflseeh9BQ0ba1vBrYtYesd2yBvLrfZDYxtEIuewkWK0OHDh20vqXYu89i7Y3ZRterVVZOZVoJusGFFciPU06dPKxZSaVX+wQMH6IuvJlGBAgUoV65cVsUo1lTwEWPFBCeeSUB+800aNvTMytmpVeSaCMqbLx+Vr5D2L/V2ijdElKaKzB6R6J076bkSJalLp87UqkXLJEn6D+hP88PDk8SrFSGupoKCg9USlyZylv74I9WqUZMmf/01Dew/gDp16GhX8Yu57+XLl9KkDiK0cpUqlD9/ftq6ZSs1aNTIqpwbN/7jlxSrKJyAgEcSEFP4wMDAtK+bSi92bdu3o+vXr1PVatXSvs4GLUFX83sZQfQL7Ucnz5xW8K1etYr69OpF8y0cjPbq3ZsK5S9An02cmCaI54fPo7Efpb3/tIcPH5r3gEhDZJ+IGFLI26GMSC2nIUzXJF3/kFDqz+6w9uzbK6fmULVyZdqwaZOiWCRSrAfF9+MzzzxrTpNWB1FRUTQnfK5Z/MEDB6lZ8+bmcxyAgKcSkOUKmel5oVXiS7PsxzLt7VK7zrGx91QTKXvIsmTJ4rQ88aVqZ/LL6fxGS6irIvto3HgKCQkxM+vQsSOF9g2m348fp9Jlyijx8oBv/kJz2rp1KzVt2tScVo0DuakPHz5C1aql/bTit5O/obWRkSTKWxyoNmzUkN586y26cP4CLVy4gObMmq1MG3bt1pXq1W9A8nfL5i3Uqk0b+pT3oixYtMjsfTuUR5DLV6xQRmcrV69S1hHFIasfsypbugxFrI2kEiVKqIEoiYzLly9TSRvZMlK0VGxJMiECBJwk8L9vvqUlixdTBtkY/Pglz5RVRlK+fI+L0djuPT8r0b169FReCuX+l5dCX19fZfOx6VzJw3Fl+Hky/uOPqG+fILp16ybF8oO+Xp26VKpUqTS7d7M83vxsqn+q/nLbXAmZWem5mMUV8R6XVldFtmnjRmr5+M3IRKZY8eK0c8cOsyKT+L6s7MLnzFVdkS3lacW+wdo4zn3rnbfp2LGjdOjQIRLlYwqFixSmESNH0tTvv1cU3FeTJ5su0fp1a+mLSZPoRTZGadOqNa2OWEPDXx9Grw0bpkyNVK1WlWRH/6GjRyiEXwAaN2lMIaGh5vxqHixftoyOs7Xitm1RVps85aHi75/orUDN8jxJ1hefT6SFCxZQrHhi8M+mfDGg4vPPe1IVvaYuAwYNpM5du1CNKlWpJXvF+O77KYqiIn6Oxz2KowXz5tPH48cr7d0VE0PR0dEUPm8eleUvOWTOnIne5pfDNavX0L79v5I/K5J4fpqPHzuOzp8/r+RZvuIn5W9Nfnnd+6sxLG0jIyIVWwGv6eQ0aIhua2QyGhLDBXGrYhnES8SJE39aRlGr1q1o/fr17H7FtbcSKyF2TuawcuzJU5lahR3bdyjrTLblnT51mt3VPKD6DepbXXr06MlnL9auX0e1a9aiNm3bUNWqVZV0VXjNSvJK2LRpI9WrV085VvO/smUTR8YdebTcntfmFi5eRHXq1jUXsWXzZnpnxAjzubcdTPnfd4pF5s2bN/kzHg9IPJl0bN+BLl286G1N9Yj2yDSfmJqbZmKyZ8+uGBblyp2L8rHBw7A3hlPRx+tbixYuop9WrlBe4AoUZAMkfnbsZ9dMpZ57joqwkVg+Xs99+umnacjQIVS0aFFz+2TkJi+UaR3iLX6/rpR187+bbIAWQ+si19Lvv/9Of124QJ06d3ZFBCVgQ7RLvNxOLB92lGG/7byvWL/JvLVt6NWrJy39cYlttNvnUoYsoMo3uVwNUmdX558v/vUXT2ncSqKspOyYmGiFRf361ors5k02oHgcPh7/EY3mvVs/fP8Dv6Em7k85c/oMFS9RnM6fO09xD+OUH7DJR5spX3J/M2bMlNxl5drrw4crf/14Pe/5Ss8rDwbLTK156lOThXPLQjU8nsijMWm7ZZD7djK7AEJwjoAoDldCDI+yZCRVv0EDJZtt/tKln1Pi5SFf3cLaWF42LvJDv4HNC+H16/8qvw1THWTa0cd04sRfKT9Xrpz8rMrsROonSR7FO7ePTNbSPhz9AXXr0pXGjhlD2/mTN3f5+eSbwZfkN75rV4wy4zJowEDaycZxzgRpY3oKuk0t+mdNdHhpe5PKQyJ79kRHmpYdEczTi+++8y5179HDMtp8LNM/X7hgECJz6fL2lz9PXkWJmAU5cZApUyZ6d8S7TqR8kiR6Z7Qyf9+4UeMnkY+Pdu/apUyf1LUZUZUrX57OnTtHq1aspMDigcpbmXzgrzOPjtZERtDu3bt4mvF12rhhAzVqnCi3T6/etNhJhS/ThatWrnS5/Uka4KURcm/KV8Bt71Fp7mJes5wdFmZ3O4mX4nCrWQpDm60aKQmKiY5RfpvFihVTksozYejgwfT91KnKeRvegC9T6q+++qqVqOgdO5W1tXo2L4QZM2WkOnVqm9PKaM8V1Srl58qeQxnhffrJBLOc5A5EkXTp0iW5JCQv86Pee5/y5s1L8nwrUbKE3fQn/viDXn39NcUhsKwfvti1Gw19ZSg1ScZmQFljtCvNOyN1U2QyVSCd/fCxl2cTXvEnJlMItkGmIGUE5ShUq16NBr08yNFlq3hRRGEzw6hHz548heH67Oqh3w4pi85WQlM4ieGpAvkB/fTTctrIa4OmkDGjH68JRpMoLfnBWAYxBqlbuw71ZsvN3n36KJdkNLiM/RyWL1OOpvwwRYkT56RXr1yl8fz12n79+lmKSPa4OK9HioHNw4eue1xJVrCXXBSr0rmz55KPr3W/SPNkJF+jRg0+cuWR6CVgXGiGjPqnTEm8T53Ntv/XX3k5obU5eQSveQUEPGM+N/0WOnTqaI6TA1kvEwtg00jOdLF27SdKzBQnzwBXQmj//nT27FmqUqWyU9kyZPCjM2fOOEy7ii20ly9dRlOnT09xjfkRrw1KkJdvWQqRf9OnTqPly5bT5G+/sbKGdligl1/QTZEJ1/IVKtD5s+esEMuibPWaNa3i5GQur2f155vJUWjarBnJP2fCBS5j5cpV9OnnnzmTPEka8Szt52c93ZQkkU2E7Jd7tnBhGjN2LN1jiylT+PvaNZrGN2WnztY/StP1tevWUX9WTmXZPU1gYHG6fec2Lea1gfdHv89rA02UZFV4zUy+wCtTEa6EChUr8Kfbx7qSJd2llQdj+Nxw5SXE1PjYe7E0+ZvJ3CflTFH4mwyBSV9+mcxV60sHeNO9PLCPHDlC7XnkJc+Dvy78xQZSq60T2jmTWY+ChQol2axvJykVLFjQXrTDOPmdyBei33v/PYdpbC906djJNko5H8fGJ2L5Gz5/nt3rlpF///03Lx+UtIxSjgcNfplkKrUzr1svYa8f/tn8rdLIdh+X5k+tchvvxLUnn8rtGzBgAO1gC0VT+IOH0PKNnYZ2dt3Pnj2bevZWxzBjEe9T65eMUjTVR62/csPJgm3Dhg0oN48s5RtBpn9iji8jsbr1rNfHTGXLyFUsrYryNMt6Vmq3b96iTz6dYB6hmdK5qsRM+fA3eQLj2a2aGOHIw1WC3J8/TJsKJZY8Nrev7pL1MZ6pEaOiNbxd5eBvvykWeykZMsXzC8fx48d4fSxxXS2lCsjacloH27VVKU/Wwpo1b0a9gxJnWFKqg4xOxTrZXsiRIwet4a02bXi5wTRqM6WTmZ70NFmg64gspF8oLeK1BvG/KDegLHbK2o9t2LtnDzvMLKesV9hec+d8Lr9hb4uKcierW3nkTVGMWGzXwESYXFOmQ9iLfHJB9oUN4XlxBO0JmDboZ+LpogePp3m0r0X6KDGa18fkxc5yH6RiOZt0dtcKiBhByFSw7fqYVSKLkwo8G5TWwXapYOaMGVSzVk2yNepKrh6y5aVFy8TN247SRe3cQa3ZK9K6jRsskqQAzCKlNxzqOiITgBvYbLwkb0pct3Yd7T94gCpUTOoYcx573whlpadGOM6brfPzGlz+p/OrIc4pGbLfRb4PJJ88sQ2ydib+JLOzVw4EzyZg+2Dy7Noas3bye6hdp45V5cUZQEpBXgjFsMRZJSH7M7UM1/+5Thf5I7Xt2rd3qdhNm7Y4lX5G2Ex2nOCcIYpTAg2WSNcRmYlV6dKlSf45CvN5w+P/pnzn6LJL8Uv4RyEWQloGWYTOz/tZ8ua1NmIRNzKnTp7UdC+blu1GWSDgCoE/ef/oI17bcXZUZSlbtrDInrNnCz9rGa3rcazFNqK+QUGKxx1XK9SmzROjl+Tyyvq7eD25cuWK4tQ7vbmo0n1EllznyLUI9vz84ksvpZTM6ethM2ZS9549nE6fmoTreZQ5bsxYOs3KSjYoineIm2xyK/vAFvHxoIEDFTNjMbH/ccmPqSkKeUHA8AS279iubGdo0qSxy205wBuhG/AatCcFk4uqTewTtW9wX5erJq76KrFPVWfDiJEj6L0RI5XkcFHlLDWN0s1hI4/hvJtfjSA3e0Xe1JtWTkJt61iALaM6dupEXV/spkx7yFuS7O+QhVmZTn2L5+nFK4YsVLvz0VHb8nAOAkYkIPsZZT/V/fv3KUvWLNSdX1xlg/8WtsRNbrN9/9B+tG/fXpIP42bjvadR7D6tEn+zSx7ie3/Z5zEoMvEWhJe6d3e5Pvv376fOKexFsxUqTtbTY9B0alEe2K64TpEbW3b5L+O9V2qEBWzuGsQ+CbUKVapWcVhUDTtbDBwmxgUQ8GICXbt1YyfZ3VxuYdjsWS7n0SNDo8aN3CpWHHTbej5KSZA4WE+PQVNFNnjIYPbgntNpzvLpgiiZblApDGVPAJY+11QSCzEgAAIgkISAWCOnJvixlazbIQEuqtxml1JG2azoajB9zsXVfPbSiycLBBAAARDQgoB48klVSI0FvY/Hmz+kCo1t5vTVWtvW4xwEQAAEPJRAqkZkHtqmtKpWKsauaVUlyAUBEAAB4xO4y5+qEotkcRclgyvxWOLz2EOMeN2I5+k/k8cY+QqmeO007VW8xHvOxKvPSbZ4lqDYFvBGcdN1OTfL4utifyDm96bw7/V/7Dq7Nl33tr9QZN7Wo2gPCICARxDInTcPzZo5M7EurIQesPGayVmxfGswLu4hfww0s3LdtJ5mmo5Uzln7iQm+BDF8E88lJsUnVs6ZJC8rQAnybcds2bKZlZd807FYYDG5lC4CFFm66GY0EgRAQGsC8uVqBG0IYI1MG84oBQRAAARAII0IQJGlEViIBQEQAAEQ0IYAphbd4BzLHjqWLFmieO13I7tHZJE590KFXPsmk0dUHJUwHAFZF+rUvoPiONtwlX9c4SZNm7AHkXtGrb7X19uHPUYnrhZ6fVPVbeCG9euVxVd1pWonTVwAtWjVUlkcNllCaVe6MUvKzB9Tvc8L9AiuEdi4fgP5yfexDBxkD2qxwEADt8C7qw5F5t39i9apSACKTEWYEAUCKhLAGpmKMCEKBEAABEBAewJQZNozR4kgAAIgAAIqEoAiUxEmRIEACIAACGhPAIpMe+YoEQRAAARAQEUCUGQqwoQoEAABEAAB7QlAkWnPHCWCAAiAAAioSACKTEWYEAUCIAACIKA9ASgy7ZmjRBAAARAAARUJQJGpCBOiQAAEQAAEtCcARaY9c5QIAiAAAiCgIgEoMhVhQhQIgAAIgID2BKDItGeOEkEABEAABFQkAEWmIkyIAgEQAAEQ0J4AFJn2zFEiCIAACICAigSgyFSECVEgAAIgAALaE4Ai0545SgQBEAABEFCRABSZijAhCgRAAARAQHsCUGTaM0eJIAACIAACKhKAIlMRJkSBAAiAAAhoTwCKTHvmKBEEQAAEQEBFAlBkKsKEKBAAARAAAe0JQJFpzxwlggAIgAAIqEgAikxFmBAFAiAAAiCgPQEoMu2Zo0QQAAEQAAEVCUCRqQgTokAABEAABLQnAEWmPXOUCAIgAAIgoCIBKDIVYUIUCIAACICA9gR8EjhoXyxKBIFEAtUqV6Hs2bN7PA4fX186c+oUFStenBLi4z2+vqH9QimkXz+Sn7ePj4/H1xcVBIHUEPBLTWbkBYHUEjh18iTt3ruX7t69k1pRyG9BoHCRItS7Zy9asGihRSwOQcA7CUCReWe/GqZV8TxiKFO2jGHqa6SK+vllNFJ1UVcQcJsA1sjcRoeMIAACIAACnkAAiswTegF1AAEQAAEQcJsAFJnb6JARBEAABEDAEwhAkXlCL6AOIAACIAACbhOAInMbHTKCAAiAAAh4AgEoMk/oBdQBBEAABEDAbQKaKrLLly/T/fv3Xars8WPHXErvTuKzZ87Sw4cP3cmKPCAAAiAAAjoT0FSRTZ82jTZv3uxSk+vWruNSencS9+jenc6fO+9OVuQBARAAARDQmYCmiozIdVc57dq3pw0bNqQZpksXL9K9u3epeIniaVYGBOtLYObMmVShQgX6559/9K0ISgcBEEgTAhorsqRtOHjgAH06YQINf31Y0oscExISTOFz5tq9pkbk4sVLqG9IiBqiIMNDCZw9e5YKFixIefPm9dAaologAAKpIaC7i6q7d+/Rnp9/pqxZs9ptR9PmzSmoTxCvYcVRxozqV3cWv61v2rrFbtmIND6BuLg4euedd/je8W53TXAObPx7FS1wn4DuI7K69epS8+YvcAscTzv27tOHlixe7H4rHeQ8xd7Ms7HndXlbR/A+AqLEatasSTlz5qRZs2YZpoHyPYr6detR6ZKlKG+u3PT5Z59Z1X3H9u1U5rnSFFCwEAUUKEghfYPh4d6KEE7SGwHdFZkAj49/lOwPMSi4L4XNnKF63yxasJBCQ0NVlwuBnkHAz8+PRo8erVRGFJrW4fbt2zTqvffplSFDafMm542c5Ksr0btiqH2H9lSkaFGaFWathBs2akTH//idMmfKRBevXKY54Wk39a41M5QHAu4Q8AhFJhVP7pNJFStWpL/+ukjXrl5zp40O84TzA+ClHt0dXscF4xPYv38/Zc6cmSpVqqR5Y7Jny0aNGjemlStW8P17weXype5vvvmmYoy0bu06q/yXL1+izl26WMXhBATSKwHPUWTJTC1K57w8eDDNmxeuWj8dPnyYihULpNy5c6smE4I8j8DPvP5auXJlysSjF80Dv521aNmC3Pmcyu3bt6goj8Z69elNMkU6c8Z0q+pHbYuips2aWsXZniT3cmibFucgYGQC6ltPuEFD1gR8fB2vkYnIXr17UesWLenNt96yW8JXX06iryZNsnvNXmSGDBmU6cxnCwXYu4w4LQhwv6elgonnLznv5Y92huhsleqOQtketYMVVTOS+7Q9b0FZvXo1iUMB03ruls1b6KvJXzvsJfk9bI+KomcL8v2d/E/LoQxccJ2APJ/efNv+M8p1acjhLAGPUGRE/ERL4dd2mg0zipco4bBdw998g4a9MdzhdcsL8nAIeLoAnTp31uut2Szb7WnH0g85sz/lcrVEOU3jzfVnzpyhwoULU7169SgyMpJW8BSej4XWOHLkCN26dUsx+BDPLUd4FH7ixJ9Uv0F9ys1GFCtXriD/rP7UoVNHpQ43b96kNatW0bOFi/CUYCO79dq7Zy+tjYygGrzm1rZdO7tpHj16RGsjIigPm/vXq1/fbpqUIrdt3UrDhiduSek/aCCXGUkzp0+n0R9+qGSVLQVPPeWYnTxMDx78PwqfH05SHwRtCFjef9qUiFKEgEdMLcbLiMziAWSva8LnhFNIaIi9S0qcr6+v8vYqD8eU/u3ds4dq1alDWbJkSTFtSrJwPWXejhg57MxkLkSwgqhduzZduXKF3njjDeUhPWjQIEWp2d5Du3fvViTVqlWLbty4QVN/mErDXnuNpvHfl1k5tG7Thvbt20vFWHEtW7qUxo0Zw0qtEy1auICq8nSkZThx4gQVDniGrl27xm/cbyuWkGIx+Ntvv1kmo5e6vUiNGjSkatWr8+ipENWsXoPk3nQ1HDx4kAoXKaJkE0OVQs88Q7NmhinnN/+7SYGBxZTj5P4z8XDEH/Hu37uO2LnT18n1Ia45R8D1X5hzcl1KJXtgfFNQZEuXLaUOHRPfnF0SbifxQrZWDOobZOcKojyZwPnz5ymEpwkbsdWeKLR2PCISJSZBRmW2Yf369VSqVCnlX/78+Wnq9GnKetOhQ7/R3HnzFGU09NVX6cGDB7Rxw0aa9PXXyihnyCtDSfxvnvzzpFlkx3btldFQ23ZtKUeOHDyqa0Cffv4ZSXxsbKySbvzYsSQb/MXiMIAVT4mSJWjXz7vp9q3bZjnOHMiUqO3a7cCBAymOR1YRayJo+/YoatK0mTOikAYE0gUB3RWZTP1E79ypvNn+/fffdqGv4imj7t172L3mTqQosi5du7qTFXl0JPDBBx/Q9evXafLkyeZaXLiQaA1Y32IK748//qDZs2fTKp4mHDVqlDmtHMhLU4sWLcxx/rwRX6YdW7dpbY7LmsVfmSEQ83kJcn/KvWmrLFu1asUWhffox8d7HOeyB5r2HTqY5ciBbAGIT4i3ikvpJCY6hpo0aWyVLLR/P3rA9QzjDfy7Ynbx9SZW13ECAumZgO6KTLx6yOjow3FjlcVpe50RFjabgkP62rvkclzUtm3UstWTB5nLApBBNwJigViEp9ssTemXL1+u1MdSyXzGG4i3bNlCci04ONiqvqLIsvOIyhRkdVaJs1irkzgJpkmC34//rkxB23qf8ff3V5Z2r1y5yl91iCVRfLlz50rMnIr/t/L6WOOmTa0kiELs3LkTHWCTfNkQXaBgAavrOAGB9ExAd2OP5i+IVw/H4c6d2zxds59q8bqIGmHB/AXUJwjTimqw1FKGGGLISEtGQaZw9epVxZpPDD5EwZlCil48xEzWhRAYGKgou4uXLirThaasFy9eUuLLlC3Le9WykCg2iUsSXCuOYqKjaczYMUnEDHr5ZVq9ajWVZwfICCAAAk8I6D4ie1IV+0fz5y2gAbw+oFZYw2bMLS0ehmrJhZy0JSBTijJyysabjCXI8WDeWyjTgtWqVVPi7t27p/xN6T/LBXkZ6UjIkOHJT8HPL8PjuMS/TZs3o3LlytGcWbOVeNN/03nNLSAgQPHAIXEjRo6gVStXKmtupjS7YmIoc5bMUmFTlMO/Z8+coblz5tDhQ4fo6NGjSb7dV6VqVSrE5dWvn3Q90KFQXACBdEDgya9Xq8am/Hu2qsnMGTNUM8yIjIikTjw9g2A8AsWKFVNM7aN5tCKGHuJaLE+ePMoalFiQTZw4kdqwFaKjcP7cOWrDLzBisj7piy9pNrt9EnP8zmxAJMYbo94fRT8tW66sh/UP7Uc5OW7o4CG0lacoJazdsJ4tI09T+7Ztad7ccOrSqQvt420AG7c8cT01eOhQHu33oRpVq9HiRYtpynff0fhx4xWlO+GTCTR96lRH1VPi3xv5HslG57a8b+z9kSPpzz//TJJ+JMc3Y0faCCAAAhYE+M1Ws/DlxC8Stmze7HR5PJ2UUKdWbafTp5TwjWHDE3bu2JlSMlzXkECObNmdLi0sLCyBrQ8TWPEkvPbaawns8SKhQYMG8mqUwJaMCbxh2GlZqUnIJvcpZj965EgCGzIp6XiElcAjyhTzqJ2gb5++aouEPBDwSAI+UisLvYZDENCUgGyI/o/dMTkbZCpRzNPFf6IEuX3lg5n58uVzVkS6SRccFMzbDOamm/aioemXgO7GHukXPVruDgHb74rJpl8oMXdIIg8IeA8B7dfIvIcdWgICIAACIOABBKDIPKATUAUQAAEQAAH3CUCRuc8OOUEABEAABDyAABSZB3QCqgACIAACIOA+ASgy99khJwiAAAiAgAcQgCLzgE5AFUAABEAABNwnAPN799khpwoEZB9YNvZTaPp2lgoiIYIJfMDfVqtQoTxYgEC6IIAN0emimz2zkaLEoMA8s29QKxAwEgFMLRqpt7ysrlBiXtahaA4I6EQAikwn8CgWBEAABEBAHQJQZOpwhBQQAAEQAAGdCECR6QQexYIACIAACKhDAIpMHY6QAgIgAAIgoBMBKDKdwKNYEAABEAABdQhAkanDEVJAAARAAAR0IgBFphN4FAsCIAACIKAOASgydThCCgiAAAiAgE4EoMh0Ao9iQQAEQAAE1CEARaYOR0gBARAAARDQiQAUmU7gUSwIgAAIgIA6BKDI1OEIKSAAAiAAAjoRgCLTCTyKBQEQAAEQUIcAFJk6HCEFBEAABEBAJwJQZDqBR7EgAAIgAALqEIAiU4cjpIAACIAACOhEAIpMJ/AoFgRAAARAQB0CUGTqcIQUEAABEAABnQhAkekEHsWCAAiAAAioQwCKTB2OkAICIAACIKATASgyncCjWBAAARAAAXUIQJGpwxFSQAAEQAAEdCIARaYTeBQLAiAAAiCgDgEoMnU4QgoIgAAIgIBOBKDIdAKPYkEABEAABNQhAEWmDkdIAQEQAAEQ0IkAFJlO4FEsCIAACICAOgSgyNThCCkgAAIgAAI6EYAi0wk8igUBEAABEFCHABSZOhwhBQRAAARAQCcCUGQ6gUexIAACIAAC6hCAIlOHI6SAAAiAAAjoRACKTCfwKBYEQAAEQEAdAlBk6nCEFBAAARAAAZ0IQJHpBB7FggAIgAAIqEMAikwdjpACAiAAAiCgEwEoMp3Ao1gQAAEQAAF1CECRqcMRUkAABEAABHQiAEWmE3gUCwIgAAIgoA4BKDJ1OEIKCIAACICATgSgyHQCj2JBAARAAATUIfD/02DMoSQyi/YAAAAASUVORK5CYII="
    }
   },
   "cell_type": "markdown",
   "id": "b8e77e98-583e-4264-aacc-fc051a384771",
   "metadata": {},
   "source": [
    "![image.png](attachment:e9fc2bd9-113e-4a65-b423-277b082e7456.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc30e98e-72d2-4f20-ad68-ec8356abf4ba",
   "metadata": {},
   "source": [
    "The above QPE scheme includes three components \n",
    "\n",
    "* A Hadamard transform applied to a first $t=2n$ qubit register at the begining of the circuit (t is set by the required accuracy and probability of success [[4](#NielsenChuang)])\n",
    "* An inverse QFT applied to the same register at the end \n",
    "* A modular exponentiation applied to the first and a second $n$ qubit register computing $a^{j}\\hspace{-6pt}\\mod \\hspace{-4pt} N$ for each of the values $j$ in the first register\n",
    "\n",
    "Clearly, the most difficult component to implement is the modular exponentiation which will require additional auxiliary qubits. \n",
    "Here we construct a circuit implementing the above period finding algorithm receiving classical numbers $N$ and $a$ as input and returns (with a good probability) a measured output which is a good approximation to the rational number $s/r$ above.    \n",
    "We start from modular addition, via modular multiplication to modular exponentiation and the full period finding circuit. The modular adder used here is a version of the QFT-based addition of Draper [[5](#Draper)] and is similar to the circuit suggested in [[6](#Beauregard)]. More generally, the period finding circuit here is similar to implementation of [[6](#Beauregard)] except for the fact that the modular exponentiation and the Quantum Fourier Transform (QFT) at the end are realized on a full register of $2n$ qubits (not on a single qubit as in [[6](#Beauregard)]) and the circuit therefore includes $4n+2$ qubits.   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10d6a91c-2ce6-446e-b097-a897ca0f2418",
   "metadata": {},
   "source": [
    "## Modular Addition\n",
    "The basic building block in the modular exponentiation function is the doubly controlled modular adder in the Fourier space. This circuit relies on adders in the Fourier space, which add a classical number $a$ to a quantum register, and consist solely of single qubit phase gates as shown in the figure below [[6](#Beauregard)]."
   ]
  },
  {
   "attachments": {
    "bc7f8672-d419-4bfe-a479-025c1017f057.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "id": "861c7f7d-7cef-4a37-8aa4-25a64f9ec71c",
   "metadata": {},
   "source": [
    "![image.png](attachment:bc7f8672-d419-4bfe-a479-025c1017f057.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "272ad477-a17c-4cc4-b756-b819197d5128",
   "metadata": {},
   "source": [
    "The modular adder calculates $|\\phi(b)\\rangle \\rightarrow |\\phi(b+a)\\hspace{-8pt}\\mod N\\rangle$ where $|\\phi(b)\\rangle = QFT|b\\rangle$ is the input to the circuit and $a$ and $N$ are classical values hardwired into the circuit (specifically into the phases of the adder and inverse adder circuits). the input $|\\phi(b)\\rangle$ $(b < N)$ is encoded into an $n+1$ qubit register where $n$ in the size of $N$ such that the most significant bit of the register is an overflow bit which is zero at the input and the output of the circuit. The circuit includes three adder functions and two inverse adders (subtractors) in the Fourier space as shown in the figure below [[6](#Beauregard)] (the a thick bar on the right/left side denotes an adder/inverse adder).  "
   ]
  },
  {
   "attachments": {
    "a1d2632f-1d40-4fca-bb7d-a4a41b76a12b.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "id": "0791bdb9-590b-40a4-9eb4-7953118609f9",
   "metadata": {},
   "source": [
    "\n",
    "![image.png](attachment:a1d2632f-1d40-4fca-bb7d-a4a41b76a12b.png)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "0e848d93-0ce4-48b2-9911-380b6473e92f",
   "metadata": {},
   "source": [
    "Dividing the circuit into 3 subcircuits and assuming that both control qubits are in state $|1\\rangle$ the state evolevs as follows:\n",
    "\n",
    "- In subcircuit A the value $a$ is added to $b$, that is: $|\\phi(b)\\rangle \\rightarrow |\\phi(a+b)\\rangle$ \n",
    "- In subcircuit B $N$ is subtracted from $a+b$ and then added again if $N < a+b$ \u2013 this is done by checking the msb of $\\phi(a+b)$ which will be in the state $|1\\rangle$ iff $N < a+b$. The value of the msb is checked by applying inverse QFT to the b-register and copying the state of the msb to an auxiliary qubit and conditioning the addition of $N$ on the auxiliary qubit.\n",
    "- In subcircuit C the auxiliary qubit is reset to $|0\\rangle$, disentangling it from the b-register. this is done by first subtracting $a$ from the b-register checking whether the msb and fliping the auxiliary qubit if the msb is in state $|0\\rangle$ and re-adding $a$ to the register.\n",
    "\n",
    "In a first step we define a QFT function without swap gates. In subcircuits B and C above there is no need to introduce swap gates to (required for keeping the order of the qubits in a register). We simply keep track of the msb (which after the QFT will be at the the lsb position) and apply the CNOT gate to the 'correct' qubit. The order will be reversed again after the application of the second QFT in each circuit. In other QFT functions (used later in modular multiplication and at the end of the circuit) we keep the swap gates for clarity.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "792f975c-e7f8-4937-a1e8-837c9c3c7436",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:43.681820Z",
     "iopub.status.busy": "2024-05-07T14:40:43.681341Z",
     "iopub.status.idle": "2024-05-07T14:40:46.866864Z",
     "shell.execute_reply": "2024-05-07T14:40:46.866127Z"
    }
   },
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "from classiq import (\n",
    "    CCX,\n",
    "    CPHASE,\n",
    "    CX,\n",
    "    PHASE,\n",
    "    CInt,\n",
    "    H,\n",
    "    Output,\n",
    "    Preferences,\n",
    "    QArray,\n",
    "    QBit,\n",
    "    X,\n",
    "    allocate,\n",
    "    apply_to_all,\n",
    "    bind,\n",
    "    control,\n",
    "    create_model,\n",
    "    invert,\n",
    "    qft,\n",
    "    qfunc,\n",
    "    repeat,\n",
    "    show,\n",
    "    synthesize,\n",
    ")\n",
    "from classiq.qmod.symbolic import pi\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def my_qft_step(qbv: QArray[QBit]) -> None:\n",
    "    H(qbv[0])\n",
    "    repeat(\n",
    "        count=qbv.len - 1,\n",
    "        iteration=lambda index: CPHASE(pi / 2 ** (index + 1), qbv[0], qbv[index + 1]),\n",
    "    )\n",
    "\n",
    "\n",
    "# qft without SWAP gates\n",
    "@qfunc\n",
    "def qft_ns(qbv: QArray[QBit]) -> None:\n",
    "    repeat(\n",
    "        count=qbv.len,\n",
    "        iteration=lambda index: my_qft_step(qbv[index : qbv.len]),\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28304e01-3f61-47a9-bf39-42ce35016ee1",
   "metadata": {},
   "source": [
    "The function `ccmod_add` implements the modular adder which adds the (classical) number $a$ to the b-register modulo $N$ in the QFT space. The function receives $a$ and $N$ as `CInt`s: classical integers parameters. The un-controlled, controlled and doubly controlled adders in the QFT space are implemented by the function `phase_lad`. The functions which check the msb of the b-register and conditionally flip the auxiliary qubit is `check_msb`. Notice that at this stage, as we don't use SWAP after the QFT, the msb is the first qubit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "af7ebdcf-1357-4fca-9dbd-2b9d6994561f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:46.870293Z",
     "iopub.status.busy": "2024-05-07T14:40:46.869630Z",
     "iopub.status.idle": "2024-05-07T14:40:46.876865Z",
     "shell.execute_reply": "2024-05-07T14:40:46.876272Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq.qmod import QNum, bind, control, within_apply\n",
    "from classiq.qmod.builtins.classical_functions import qft_const_adder_phase\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def phase_lad(\n",
    "    value: CInt,\n",
    "    phi_b: QArray[QBit],\n",
    ") -> None:\n",
    "    repeat(\n",
    "        count=phi_b.len,\n",
    "        iteration=lambda index: PHASE(\n",
    "            theta=qft_const_adder_phase(index, value, phi_b.len), target=phi_b[index]\n",
    "        ),\n",
    "    )\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def ctrl_x(ref: CInt, ctrl: QNum, aux: QBit) -> None:\n",
    "    control(ctrl == ref, lambda: X(aux))\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def check_msb(ref: CInt, x: QArray[QBit], aux: QBit) -> None:\n",
    "    within_apply(lambda: invert(lambda: qft_ns(x)), lambda: ctrl_x(ref, x[0], aux))\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def ccmod_add(\n",
    "    N: CInt,\n",
    "    a: CInt,\n",
    "    phi_b: QArray[QBit],  # b in fourier basis\n",
    "    c1: QBit,\n",
    "    c2: QBit,\n",
    "    aux: QBit,\n",
    ") -> None:\n",
    "    ctrl = QArray(\"ctrl\")\n",
    "    bind([c1, c2], ctrl)\n",
    "    control(ctrl, lambda: phase_lad(a, phi_b))\n",
    "    invert(lambda: phase_lad(N, phi_b))\n",
    "    check_msb(1, phi_b, aux)\n",
    "    control(aux, lambda: phase_lad(N, phi_b))\n",
    "    within_apply(\n",
    "        lambda: invert(lambda: control(ctrl, lambda: phase_lad(a, phi_b))),\n",
    "        lambda: check_msb(0, phi_b, aux),\n",
    "    )\n",
    "    bind(ctrl, [c1, c2])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebd310e1-8e12-4114-828a-30db70957e05",
   "metadata": {},
   "source": [
    "The phases for the QFT-based quantum adder are generated using the builtin-function `qft_const_adder_phase`, which implements the following logic:\n",
    "\n",
    "```python\n",
    "def qft_const_adder_phase(bit_index: int, value: int, reg_len: int) -> int:\n",
    "    bit_array = [int(bit) for bit in bin(value)[2:].zfill(reg_len)]\n",
    "    return sum(2 * pi / (2**(pos_index+1)) for pos_index in range(reg_len - bit_index) if \\\n",
    "               bit_array[bit_index + pos_index])\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28e50aa8-43e2-4164-a7c9-d3e6d96a8acc",
   "metadata": {},
   "source": [
    "In order to check the modular addition circuit we create a main function which includes the `ccmod_add` between a QFT at the beginning and an inverse QFT at the end. We set the classical input the modulo number (15) and the classical value to add (9), and set the input state of the b-register by applying X-gates to chosen qubits (here we flipped the forth qubit so the value of the register is 8)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6af345fa-92a7-481e-bd3e-ccdaa6a2fa99",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:46.879233Z",
     "iopub.status.busy": "2024-05-07T14:40:46.879052Z",
     "iopub.status.idle": "2024-05-07T14:40:46.925584Z",
     "shell.execute_reply": "2024-05-07T14:40:46.924818Z"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from classiq import show, synthesize, write_qmod\n",
    "from classiq.qmod import QNum, inplace_prepare_int\n",
    "\n",
    "modulo_num = 15\n",
    "reg_len = math.ceil(math.log(modulo_num, 2)) + 1\n",
    "a_num = 9\n",
    "\n",
    "b_initial_value = 8\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def main(b: Output[QNum], ctrl: Output[QArray[2]], aux: Output[QBit]) -> None:\n",
    "    allocate(reg_len, b)\n",
    "    allocate(2, ctrl)\n",
    "    allocate(1, aux)\n",
    "\n",
    "    # set initial values for the addition\n",
    "    inplace_prepare_int(b_initial_value, b)\n",
    "    X(ctrl[0])\n",
    "    X(ctrl[1])\n",
    "\n",
    "    # perform the addition in fourier basis and then transform back\n",
    "    within_apply(\n",
    "        lambda: qft(b), lambda: ccmod_add(modulo_num, a_num, b, ctrl[0], ctrl[1], aux)\n",
    "    )\n",
    "\n",
    "\n",
    "qmod = create_model(main)\n",
    "\n",
    "write_qmod(qmod, \"doubly_controlled_modular_adder\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03910079-42de-4cf5-9604-b1ced1d9b510",
   "metadata": {},
   "source": [
    "Once we have created a model of the circuit, we can synthesize it and view the circuit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4d1ccf9b-eea7-42a3-86c6-f0ea815fb32f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:46.928578Z",
     "iopub.status.busy": "2024-05-07T14:40:46.928000Z",
     "iopub.status.idle": "2024-05-07T14:40:52.653944Z",
     "shell.execute_reply": "2024-05-07T14:40:52.653209Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Opening: https://platform.classiq.io/circuit/c56d0213-65f9-4147-b112-f225f76e0a29?version=0.41.0.dev39%2B79c8fd0855\n"
     ]
    }
   ],
   "source": [
    "from classiq import show, synthesize\n",
    "\n",
    "qprog = synthesize(qmod)\n",
    "show(qprog)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20ac31c9-e566-4149-a398-3a843c22538f",
   "metadata": {},
   "source": [
    "We now can execute the synthesized circuit on a simulator (we use the default simulator) and check the outcome."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8ce57936-ca1c-40ed-a6a0-e3505c3e2de9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:52.656849Z",
     "iopub.status.busy": "2024-05-07T14:40:52.656596Z",
     "iopub.status.idle": "2024-05-07T14:40:54.274991Z",
     "shell.execute_reply": "2024-05-07T14:40:54.274217Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'01100010': {'b': 2.0, 'ctrl': 3.0, 'aux': 0.0}}\n"
     ]
    }
   ],
   "source": [
    "from classiq import execute\n",
    "\n",
    "results = execute(qprog).result()\n",
    "res = results[0].value\n",
    "\n",
    "print(res.parsed_states)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50bbc2f4-e400-4173-a0b9-e8e9c3a6a96f",
   "metadata": {},
   "source": [
    "As expected the value of the b-register is $2=8+9 \\hspace{-4pt}\\mod \\hspace{-3pt}15$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93a5f429-b81a-40b8-b3d4-d155474f004c",
   "metadata": {},
   "source": [
    "## Modular multiplication\n",
    "A controlled modular multiplication circuit which receives as input $b$ (in the b-register) and $x$ in additional x-register and outputs $|(b+xa) mod N\\rangle$ is comprised of repeated application of the doubly controlled modular adder adding $2^{i}a$ for $i=0,...,n-1$ where one of the controls in each of the modular adder is the suitable qbit of the x-register as in the following figure [[6](#Beauregard)]."
   ]
  },
  {
   "attachments": {
    "612a0423-454e-4a1a-8374-65e694a6e365.png": {
     "image/png": "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7pHC/yAwdOhQ9dprr/1zosi3hx9+WF1yySVFSsnlUhCILfMSdjB9+vRRN9xwg/rrr7/C3pq68uwOfv/991iOC2kaUjXHcWLZvzh0it0af0LhEGjbtq36/PPP1ccffxzuxgyVPuOMM9R5550X2xH/+eef6vvvv49t/8J2DOby8ccfT9WYwmJQrfKpYV6WXnpptddee6m77rqrWljFut6XX35Z7b333mr99dc3f+uss47aeOON1dFHH62+/PLLmvYdRuqyyy5TLC5rr722atmypfncfvvt1ejRo0OpB2s6kCo2PmvWLNWtWzeDTbNmzRR/rVq1Uj169FAfffRRFVtOV9WnnXaauuiii9I1qAqOZpNNNlGo495///0K1lpeVWxmTj31VLXZZpuZ90KLFi3M87/bbrupyZMnl1d5je9eZJFF1DHHHKOuvvrqGvckhc3rHXAs6cADD3S++OKLUH3TPwKnXbt2jpa+hLovyYW1JMMZMGCAs/LKKyPKqPenfzxO48aNnfvvv78mw5wzZ46jF2FnqaWWqtc3+rvccss5W2+9tfPNN9/UpH9xaHTEiBHOKqus4osPGHFt5MiRcehqpH244oornAkTJoRuc9ddd3U+++yz0Pcl8Yb27duH7vaLL77o9OrVK/R91bjh+eefd5o0aeIstthivs//Siut5Gim3tG2T9VoPnSdWi3pgF8Y0tIk84774YcfwtwmZYsgkBrJC3zlsssuq3bffXc1btw4DjNBJ510krr++uvz2gehppk7d646/PDD1ZQpUyLFBONJ/XJVb731Vl6jNXZdL7zwgtppp51iq+qqJmijRo1SQ4YMKSgdQ3I2cOBAI6WqZl/SUje7+Isvvjgtw6n4ONq0aaO+/fZb9eGHH1a87jAVvvfee2qfffYxar58zhYYGN93331Kb2bDVB2rsosuuqjCrOHaa6+NVb+S3plUMS9MxgknnGBEdJppS/rcFO3/q6++qm6//XaFjUsx4iWgd1uR2lL07t1bffrpp8W6ZtRGiLHPPvvsomXTVAD7jMGDBwfykMGrBHuFWqsAk4D/LrvsombOnKm05DYJ3a1JH08//XR14YUX1qRtGuX9vP/++wd6nvE4mzp1qmFiatbhMhtG/auliEZlV2ZVcvvfCCSaecEb6auvvsqZzIYNG5rdPtx62unEE09UYVwfwQqj5igIpmX69OmBDagxUL3tttsy9eMeNGhQvee30Nwwf0hphP5B4Ndff/WVIJx88sni5aFhgkmYPXu2Aic3afV6TY2bJ02apLRqz92lgt8t816wUEwu+q1LWi2m2MwhJReqDAKJZF6effZZo2bACAqxo3cHwaKu9eWp9mjBKv+DDz4I9RTwAovKnRzmMQxjxUCIh8DcZoWeeuqpUM8oKsDHHnssK/AUHCfP1n777af69++vhg8frrTdVA6j3LFjR4URe5hwCwUbTNhFmBbeizgx8FvUdiXq9ddfzxlFLY2bCW0RNiYPKmZU4HGlYusSku+77767HiMZ1/HEvV//jnsHvf0bP368IgYMYkS8Md59912ljb5yiq244opqiy22MDEi9thjD3PtmWeeMffkFEzwgTb+CqQu8g4RPfe5557rPV3x4wcffDBnMQnSAC6S11xzjdIGcUGKJ74MdgdhSRs2RzJ/YftVTnncSfktByVUZ/y+taG6YV6wcRszZoxxwV9hhRXqqjn++OPV5ZdfHmvX4LrOVvhLz549zUIPs8tGB/Uktmd4IFraYYcdzHkYAm3Ub0/7fsI4XHnllb7XSjn53HPPhb6N9wPjWHPNNUPfG/YGGI211lor8G1B1qUGDRoYj8JbbrnFeIEGrlwK+iKQKOZl3rx56sgjj1T9+vWre9mNHTvWd2CUXX311euu8cBvs802dcdJ/8Ku5aabbgo9jCWXXDISHLDHeemll0L171//+pdx807TPBUCAOlgWFp88cUjmb+w/SqnvPYoCXU77wDUw0hYoa5duxopDG6pbmJRXmONNdynMvEdOzhCRrz55puK54U/3hdefGBqsCfB0aEYVfq5o39hpSioXjbddFPzjijW33KvB8HEthFmXWLM2267rb1VPstAIFHMC+JPdJ9wxZZY8LxEBEliixDTwBLxRfhLCyEWZmcZlogDg2dPtQljVHZ9Xl17oXbZNbMLRwWQBVp++eUVkpQwxEIfxfyF6VOUZVEDIdXDm8j92/cuzDx3SGOi9rCLEot8baGSQTLllmZ58eFeVMidO3dWxMgqRksssURFnztiPL3zzjvFms25zsare/fuSodXyDlf64Og6xLPLp6VXjOHWvc/qe3nblViPgp2EvwIi4nzhg0bps4666yYj6a87vHiRuzrfoEXq5EffSkMT7F6/a4TMI/dcRjiJbrllluG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yNAzM0yCEd54443qk08+UW3btlVjx441Oa2uv/561aFDB7Xiiiuqs88+OzN4yECDI5Aa5oXsyo0aNQo+cilZVQSmTp1q7FvCNIIhL66TQoIACCBFZUMim5J0Pw+77LKLibiNPdxBBx2kttxyS3XUUUepVq1aqRdeeEHhhCAkCHgRSA3z8t577ymrP/UOUo6jRwBDy2LqIm+vKE94cCFBwCKA/daXX35pD+UzpQh0797deJbxHp82bZqR2D777LNq3XXXTemIZVjlIpAabyOS2RV60IkXgFdLFggJxsMPP1ww9ku1ceAlFJbIbzJ48GB1ww03hL01VeUJl06MC3IcZYEGDRqkdtppJ9+h8psm103YVBi+lcnJWCNAMtL11lvP/MW6o9K5WCCQGublzTffVD169MgLKvYUWbGpYDHAyI18IbUi+hA2rDf5ms4991x14IEH1qrbsWhXEjP+Mw2oDLCJqOWz/E9v5JsgIAjEBYHUqI1eeukltckmm8QF18z3wxrbhQGiYcOGskiFASwDZVEnLFy4MAMjzd4QMeo//vjjzd+7775bDwCM/e317777rt51OZFtBFIheSFGAPYuZE0WigcC7dq1MzF3gnob0euWLVuqrKV3iMdsxbcXuEv/9NNPxgYCzxOh9CCAITbJFyGCaV588cU5gxs/fnzd9QEDBtRUDZ7TMTmIBQKRSF4wwApDRGQN42Fw0UUXqRNOOCFME1K2ygjgKYKdUdCggUTazIpNUpWhT131ffv2VZdffnmgccEsv/POO4HKUujHH380Hi2Bb0hIQYycSccRlJBsvPzyy0GLV7zcPffcU69Ov3P1CkV84q233grliEBwzk8//TTiXmajuUiYF+wfwhC5ejA4DUJTpkwx+X1at24dpLiUiRABXB6xYSm2Y8bF/eabb1aS3yTCyUlQU6S5wAvto48+KtprFpcw0ZqR1hIgEWPxNNGrr75q8ocFHRPGsmwAiXwdNZHKhBxHBKSzRNwn3u1cixOxIcOAPCjNnz9fDR06NGhxKRcCgUiYlxD9MUVPOumkQJlE2TWdeeaZavjw4WGbkPIRIUC8BtymYS7xGPnPf/5jWl5mmWVM/AYMMVmYsJEREgT8EECKh+TlmGOOMXmx/MqUeo7Ept26dcu81I+AgHvuuacJElcqlqXet91225kYXW5JCyojPO723nvvUquN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"
    }
   },
   "cell_type": "markdown",
   "id": "5d832454-e091-4cc2-af9b-ae54f813d836",
   "metadata": {},
   "source": [
    "![image.png](attachment:612a0423-454e-4a1a-8374-65e694a6e365.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75099a4a-fe73-462a-8157-9c4bba8c0b9b",
   "metadata": {},
   "source": [
    "The `cmod_mult` function implements the above circuit and."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1f000418-d89b-4e6f-bb7c-56437e4c645c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:54.278416Z",
     "iopub.status.busy": "2024-05-07T14:40:54.277980Z",
     "iopub.status.idle": "2024-05-07T14:40:54.282861Z",
     "shell.execute_reply": "2024-05-07T14:40:54.282292Z"
    }
   },
   "outputs": [],
   "source": [
    "@qfunc\n",
    "def cmod_mult(\n",
    "    N: CInt,\n",
    "    a: CInt,\n",
    "    b: QArray[QBit],\n",
    "    x: QArray[QBit],\n",
    "    ctrl: QBit,\n",
    "    aux: QBit,\n",
    ") -> None:\n",
    "    within_apply(\n",
    "        lambda: qft(b),\n",
    "        lambda: repeat(\n",
    "            count=x.len,\n",
    "            iteration=lambda index: ccmod_add(\n",
    "                N, (a * (2**index)) % N, b, x[index], ctrl, aux\n",
    "            ),\n",
    "        ),\n",
    "    )"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "846943ee-7d81-444b-bea0-36de82110e70",
   "metadata": {},
   "source": [
    "The above circuit outputs the state $|(b+xa) \\mod N\\rangle$ in the b-register (assuming the control is in state $|1\\rangle$) however the required output is $|xa \\mod N\\rangle$. This output can be obtained by conditionally swapping the b and x registers and applying the inverse of the modular multiplication circuit for the $a^{-1} \\mod N$ classical value with input $b=0$, as in the following construction [[6](#Beauregard)].\n",
    "  "
   ]
  },
  {
   "attachments": {
    "227d3268-5463-478e-9d65-0699493058ed.png": {
     "image/png": "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3nub8ePHm19++cWJBGeeeWa3MME0DBkyxHTq1Cl8Wa5/I9pknBBvslv5448/zGyzzebGar311jNXXXWVY/Zy3YkyjTvhhBPMqaeeahBnKzUPAtNPP73Zdddd3Tt34IEHZtYx5rU+ffoYRPzheW3GGWc0F198sdlmm20ya0+1Nzr66KPNhRdeaM4///xqq9DrWoOArZK6dOmS+Mr333/fykOZ+LosL6CNiyyyiJ1yyimt4Br5J8yD3X///bNsVqvuJTpXK5KSyL74Ps4999z2pptuatV9srz4yCOPtCJNKNmnKaaYwgozZN98880sm1XyXieddJJ97rnnSp4vdWLnnXe2YttQ6rQezwEC1cyFwrjbtdZay/7555+Z9EA2DXbhhRcuO6/xPgkTk0l7/E123313+8UXX/ifsT5Fumg7d+5sv/3221jltVC6CFRt01ANo7LkkkuaWWaZxYwePbqay2t+DcZJW265pfn8888NYu9ShOTh7rvvNldeeWWpIrk5jhri4IMPNuhRy9GECRPMMcccY2SRLVcsF+eGDh3qdmk//vhjyfbIa2K+/PJL0717dzN58uSS5fJ+4sQTTzRnnnlm3pup7UuIADv7HXbYwfAs15p+++03N6/J4lx2XuN9QqqFhC7PJBsCI5sGJxnJczubtW2ZqSc8gIhcTz75ZLfo+mN5+TzttNPMZ599Fqs5MA4DBgwwu+22m1NbxLqoDoX22msv83//93+x7iycu9lzzz0Nlvt5JVQr2MeUYxiCbYdx6Nevn7niiiuChxvm+worrGBkN2reffdds/TSSzdMu2vRUNSaiNjTJNntm3p5dvXq1ct069bN8I7W0k6qf//+biMUBzfeq9NPP93Na6j68kpsBlBR8DzMOeeceW1mU7arZpIGdnoYqIVdi5ZZZhkzzTTT5G5Hi2SByQO9eFxid37ttdfGLZ55OaQMSSz2aSCGkm+88UbmbY17w1tuucV8//33cYs73e3999/vFt7YF9WpINIgGLcwwWifddZZ4cNt7vdrr71mPvzww1T/snBrLTUXYlO09dZbm9tuu61mY8m8xjuTZF7j/bruuutq1qakFUe9F0gbDjvsMDNo0KCk1Wn5ViKQOtPAC4J1Ky/DfffdZ9q1a9di55rHSfCjjz4yf//9dyI4MSbKszfIM888k2iBpfMwQk888UQiHLIs/OCD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RUARUATiIdDmmAas0uOGio4HYXQporCVIlzplEzZxFNE58xinLiPkiKgCCgCikA8BNSmIR5OWkoRUAQUAUVAEWjzCCjT0OYfAQVAESiNwB9//GEkxHXpAnpGEVAE2hQCyjS0qeHWzlaLABlQP//882ovb9jrJOS4ueyyyxq2/dpwRUARSBcBZRrK4Pnwww+bnj17GiK4rbPOOuaggw4ykruhzBV6KmsE8Jo4//zzzXbbbWc6derkskaywKe9O2bc064za6yquR+RLO+55x7z22+/VXO5XqMIKAJNhoAyDSUGFNfMrbfe2jz33HNuMZLsieb66683RPaTjJAlrtLDWSIgianMeuut51L54qaJxwWL+wknnOC+1yLscJb9y8O9eO5hnK+55po8NEfboAgoAnVGQJmGiAF48MEHjWRNNLhNjhs3zgwZMsQ888wzLg6AZNoz++yzT8RVeihrBI499lgjqdbNXXfd5cZn8ODBbowQp7/99tuauyGlAeF5v/322w32DXHoxx9/JHtuUVHJRlrSvbaooP5QBBSBXCOgTEPE8Ei6WBeU6ZJLLilyCyQ75IUXXmjIC/D9999HXKmHskKA4Fm33nqry9S54447Ft22d+/eZq+99jIsVLUkgnfVgmopIUHNkDS4GS7CPXr0cJK2OP1dZplligJmPfnkk0ZSIJvu3bub/fffP04VFctMmDDB9OvXz41zxcJaIBcIPProo7loR9aNOPfccw3Pa7OQMg2hkWSH9NZbb5mNNtrIELkxTNg1SC76yEiP4bL6u3YIIElgrKKCM5G58MYbb3QMXq1a8P7775tTTz21JtWTOvmhhx5Kve433njDLL300s5GIVj5BRdcYEgGhWTN0+jRo11W2pVWWsm8+uqrZr/99jM333yzwYakEt19990u2qcvh0TomGOOMY888og58MAD/eFWfT7++OMuFXqtGLdWNU4vjkQA26O2SB07dnSS62bpuzINoZH87rvvzK+//moWXXTR0Bn9mScEPv30U9eceozTF198YUjpG05djaHksGHD3GJ27733xoILW4zbbrvNfPbZZ2bSpElO1XL00Uc7484RI0bEqiNuIRgAjEVRsQWJBX2FFVYwN910k0G6BpHGHqlAr169DJkFYSp22WUXx4wFr436vtZaa5m///7b/PPPP+abb74xhGGnb1NPPbVZY401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UAQUgaZHQJmGMkPcrl07c/rppxsMALFxUMonAr169TLrrLOOy2xJ5EclRUARUAQUgdogoExDBVwPP/xwl076qKOOciGKKxTX03VAALuOa665xgV2YpyUFAFFQBFQBGqDgDINFXBFPcGChIcCKbOV8okAkR/79etnbrnlFicZymcrtVWKgCKgCDQ2Aso0xBg/chrgYnnttdeal19+OcYVWqQeCODlQgjpQw45pB6313sqAoqAItD0CCjTEHOIsW3AxmHixIkxr9BiWSNAVsurr77afPPNN1nfWu+nCCgCikCbQECZhohhjsqCSBAlvCmU8oMA4xROEtalSxez77775qeR2hJFQBFQBJoIAQ3uFDGYQ4cOjThqzGabbaaxACKRqc/BP/74I/LG119/veFPSRFQBBQBRSBdBFTSkC6eWpsioAgoAoqAItC0CLQ5ScNXX31l+vd0upKOAAABe0lEQVTvX/MBHT16tJl22mkNao0wqV3EfxEhh8fss88ehsf89ttvZty4cZmM0/jx41vcXw8oAoqAIqAIRCMwhYTetdGnmvPoa6+95vz5a907XDRJdDXbbLO1uBXHCUbU1mnUqFGGjJRhmjx5svn111/NfPPNFz6V+m9CUIczmaZ+E61QEVAEFIEmQaDNMQ1NMm7aDUVAEVAEFAFFIHME1KYhc8j1hoqAIqAIKAKKQGMioExDY46btloRUAQUAUVAEcgcAWUaModcb6gIKAKKgCKgCDQmAso0NOa4aasVAUVAEVAEFIHMEVCmIXPI9YaKgCKgCCgCikBjIqBMQ2OOm7ZaEVAEFAFFQBHIHAFlGjKHXG+oCCgCioAioAg0JgLKNDTmuGmrFQFFQBFQBBSBzBFQpiFzyPWGioAioAgoAopAYyKgTENjjpu2WhFQBBQBRUARyBwBZRoyh1xvqAgoAoqAIqAINCYCyjQ05rhpqxUBRUARUAQUgcwR+H+31GE52/SmWQAAAABJRU5ErkJggg=="
    }
   },
   "cell_type": "markdown",
   "id": "d8bd9535-4270-4f53-8842-26e0e227ab12",
   "metadata": {},
   "source": [
    "![image.png](attachment:227d3268-5463-478e-9d65-0699493058ed.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c63e48de-c219-4ff1-8e6e-0cbc9d44c88c",
   "metadata": {},
   "source": [
    "After the swap the x and b registers are in the state $|ax\\hspace{-6pt} \\mod \\hspace{-4pt}N\\rangle|x\\rangle$ and the inverse multiplication function (by $a^{-1}$) will send them to the state \n",
    "$|ax\\hspace{-6pt} \\mod\\hspace{-4pt} N\\rangle|x- a^{-1}ax\\rangle = |ax \\mod N\\rangle|0\\rangle$. Thus, the x-register carries the required output while the state of the b-register is $|0\\rangle$ at the output. The `cmod_mult_pair` function implements this circuit using the `c_swap` and `creg_swap` functions which implement swap between qubits and registers respectively.    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5601891d-500d-409a-88ac-f8a833520d45",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:54.285323Z",
     "iopub.status.busy": "2024-05-07T14:40:54.284975Z",
     "iopub.status.idle": "2024-05-07T14:40:54.300373Z",
     "shell.execute_reply": "2024-05-07T14:40:54.299697Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq.qmod import SWAP, free\n",
    "from classiq.qmod.symbolic import min, mod_inverse\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def multi_swap(x: QArray[QBit], y: QArray[QBit]) -> None:\n",
    "    repeat(\n",
    "        count=min(x.len, y.len),\n",
    "        iteration=lambda index: SWAP(x[index], y[index]),\n",
    "    )\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def cmod_mult_pair(\n",
    "    N: CInt,\n",
    "    a: CInt,\n",
    "    x: QArray[QBit],\n",
    "    ctrl: QBit,\n",
    "    aux: QBit,\n",
    ") -> None:\n",
    "    b = QArray(\"b\")\n",
    "    allocate(x.len + 1, b)\n",
    "\n",
    "    cmod_mult(\n",
    "        N,\n",
    "        a,\n",
    "        b,\n",
    "        x,\n",
    "        ctrl,\n",
    "        aux,\n",
    "    )\n",
    "    control(ctrl, lambda: multi_swap(x, b))\n",
    "    pass\n",
    "    invert(\n",
    "        lambda: cmod_mult(\n",
    "            N,\n",
    "            mod_inverse(a, N),\n",
    "            b,\n",
    "            x,\n",
    "            ctrl,\n",
    "            aux,\n",
    "        )\n",
    "    )\n",
    "    free(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "330131a8-27a6-43d0-b1ba-365b3068a9e4",
   "metadata": {},
   "source": [
    "## Modular Exponentiation\n",
    "The above circuit can be applied repeatedly to achieve modular exponentiation. Specifically, taking an $m$ qubit register carrying value $M$ and applying the `cmod_mult_pair` function in $M$ times in sequence cascading the control over the qubits of m-register multiplying by values $a^{2^{0}}, ..., a^{2^{m-1}}$ will take the input state $|M\\rangle_{m}|1\\rangle_{x}|0\\rangle_{b}$ to the output state \n",
    "$|M\\rangle_{m}|a^{M}\\mod N\\rangle_{x}|0\\rangle_{b}$ as required (for clarity subscripts were added to identify the registers). The `mod_exp_fuc` below implements the modular exponentiation, and accepts the classical numbers $N$ and $a$.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0ce01115-e6f2-4ee1-9353-2a34b86685fe",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:54.304631Z",
     "iopub.status.busy": "2024-05-07T14:40:54.304239Z",
     "iopub.status.idle": "2024-05-07T14:40:54.315156Z",
     "shell.execute_reply": "2024-05-07T14:40:54.314445Z"
    }
   },
   "outputs": [],
   "source": [
    "@qfunc\n",
    "def mod_exp_func(\n",
    "    N: CInt,\n",
    "    a: CInt,\n",
    "    x: QArray[QBit],\n",
    "    m: QArray[QBit],\n",
    "    aux: QBit,\n",
    ") -> None:\n",
    "    repeat(\n",
    "        count=m.len,\n",
    "        iteration=lambda index: cmod_mult_pair(\n",
    "            N, (a ** (2**index)) % N, x, m[index], aux\n",
    "        ),\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b709bb1-15f8-4bdf-a199-3df309e1545c",
   "metadata": {},
   "source": [
    "## Quantum Period Finding\n",
    "Using the modular exponentiation function it is straightforward to implement the complete period finding algorithm - one needs to apply the Hadamard transform to the m-register at the beginning of the circuit and an inverse QFT at the end. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "8ef24bb4-b063-42d6-a5ea-ddcd5310ae13",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:54.321999Z",
     "iopub.status.busy": "2024-05-07T14:40:54.321455Z",
     "iopub.status.idle": "2024-05-07T14:40:54.327213Z",
     "shell.execute_reply": "2024-05-07T14:40:54.326648Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq import Constraints\n",
    "from classiq.qmod import hadamard_transform\n",
    "\n",
    "modulo_num = 6\n",
    "reg_len = math.ceil(math.log(modulo_num, 2)) + 1\n",
    "a_num = 5\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def main(\n",
    "    x: Output[QArray[QBit]],\n",
    "    power: Output[QArray[2 * (reg_len - 1)]],\n",
    "    aux: Output[QBit],\n",
    ") -> None:\n",
    "    allocate(reg_len - 1, x)\n",
    "    allocate(2 * (reg_len - 1), power)\n",
    "    allocate(1, aux)\n",
    "\n",
    "    hadamard_transform(power)\n",
    "    inplace_prepare_int(1, x)\n",
    "\n",
    "    mod_exp_func(\n",
    "        modulo_num,\n",
    "        a_num,\n",
    "        x,\n",
    "        power,\n",
    "        aux,\n",
    "    )\n",
    "    invert(lambda: qft(power))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "8e9d0b08-f3f8-4e95-a468-bfeec010d97c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:40:54.329990Z",
     "iopub.status.busy": "2024-05-07T14:40:54.329475Z",
     "iopub.status.idle": "2024-05-07T14:46:00.091038Z",
     "shell.execute_reply": "2024-05-07T14:46:00.090294Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Opening: https://platform.classiq.io/circuit/30af4bd3-ee9d-4f9c-aae6-782e25beafaa?version=0.41.0.dev39%2B79c8fd0855\n"
     ]
    }
   ],
   "source": [
    "constraints = Constraints(max_width=14)\n",
    "qmod = create_model(main, constraints=constraints)\n",
    "write_qmod(qmod, \"shor_modular_exponentiation\")\n",
    "\n",
    "qprog = synthesize(qmod)\n",
    "show(qprog)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "0aef2760-aa9a-4710-8c60-08333a0a9b0b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:46:00.095502Z",
     "iopub.status.busy": "2024-05-07T14:46:00.094794Z",
     "iopub.status.idle": "2024-05-07T14:46:15.474839Z",
     "shell.execute_reply": "2024-05-07T14:46:15.474129Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq import execute\n",
    "\n",
    "results = execute(qprog).result()\n",
    "res = results[0].value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "b43b92b0-ef5b-494b-bdc5-e70c473bd428",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T14:46:15.480093Z",
     "iopub.status.busy": "2024-05-07T14:46:15.478900Z",
     "iopub.status.idle": "2024-05-07T14:46:15.495125Z",
     "shell.execute_reply": "2024-05-07T14:46:15.494438Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'x': 1.0, 'power': 0.0, 'aux': 0.0}: 271,\n",
       " {'x': 5.0, 'power': 32.0, 'aux': 0.0}: 264,\n",
       " {'x': 5.0, 'power': 0.0, 'aux': 0.0}: 240,\n",
       " {'x': 1.0, 'power': 32.0, 'aux': 0.0}: 225]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res.parsed_counts"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5668d32e-0d55-4e93-ae84-ec165c0c210c",
   "metadata": {},
   "source": [
    "We obtained two results for the qutput register (the m-register) $32$ and $0$ each with probability roughly $1/2$. Interperted correctly as binary fractions (dividing by $2^{6}=64$) these are $0$ and $1/2$. Indeed the period is the denominator of the first result $2$.   "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "169a1e57-fed2-4e27-a4c1-9206fa5ba021",
   "metadata": {},
   "source": [
    "## References\n",
    "\n",
    "<a id='IntegerFactor'>[1]</a>: [Integer Factorization (Wikipedia)](https://en.wikipedia.org/wiki/Integer_factorization)\n",
    "\n",
    "<a id='Shor94'>[2]</a>: [Shor, Peter W. \"Algorithms for quantum computation: discrete logarithms and factoring.\" Proceedings 35th annual symposium on foundations of computer science. Ieee, 1994.](https://ieeexplore.ieee.org/abstract/document/365700)\n",
    "\n",
    "<a id='ShorSteps'>[3]</a>: [Shor's Algorithm Procedure (Wikipedia)](https://en.wikipedia.org/wiki/Shor%27s_algorithm#Procedure)\n",
    "\n",
    "<a id='Nielsenchuang'>[4]</a>: Nielsen, Michael A. & Isaac L. Chuang (2001), \"Quantum computation and quantum information\", Cambridge Univ. Press. tific. ISBN 978-9812388582\n",
    "\n",
    "<a id='Draper'>[5]</a>: [T. G. Draper, Addition on a Quantum Computer, 2000.](https://arxiv.org/pdf/quant-ph/0008033.pdf)\n",
    "\n",
    "<a id='Beauregard'>[6]</a>: [S. Beauregard, \"Circuit for Shor\u2019s algorithm using 2n+3 qubits\", Quantum Information & computation, Vol 3, Issue 2, 2003.](https://arxiv.org/pdf/quant-ph/0205095.pdf)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
